/****************************************************************************

 Copyright (C) 2009 Jean Pierre Charalambos. All rights reserved.

 Jean Pierre Charalambos (http://dis.unal.edu.co/profesores/pierre/) is an
 Affiliate Associate Professor of the Faculty of Engineering at National
 University of Colombia (http://www.unal.edu.co/).

 This file is part of maku version 0.2.

 http://code.google.com/p/maku/
 email: jpcharalambosh@unal.edu.co

 This file may be used under the terms of the GNU General Public License
 versions 2.0 or 3.0 as published by the Free Software Foundation and
 appearing in the COPYING file included in the packaging of this file.

 This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

*****************************************************************************/

#ifndef VIEWER_H
#define VIEWER_H

#include "scenet.h"
#include <QGLViewer/qglviewer.h>

struct MyTraits : public OpenMesh::DefaultTraits {
    HalfedgeAttributes ( OpenMesh::Attributes::PrevHalfedge );
};

typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits>  MyMesh;
typedef SceneT<MyMesh>                            Scene;

using namespace Qt;
using namespace qglviewer;
using namespace std;

class Viewer : public QGLViewer {

        Q_OBJECT

    public :

        Viewer ( Scene * const s, QWidget * parent=NULL, const QGLWidget* shareWidget=0 )
                : QGLViewer ( parent, shareWidget ), scene ( s ) {
            initViewer();
        }
        Viewer ( Scene * const s, const QGLFormat & format, QWidget * parent=NULL, const QGLWidget* shareWidget=0 )
                : QGLViewer ( format, parent, shareWidget ), scene ( s ) {
            initViewer();
        }

        Viewer ( QWidget * parent=NULL, const QGLWidget* shareWidget=0 )
                : QGLViewer ( parent, shareWidget ), scene ( 0 ) {
            initViewer();
        }

        Viewer ( const QGLFormat & format, QWidget * parent=NULL, const QGLWidget* shareWidget=0 )
                : QGLViewer ( format, parent, shareWidget ), scene ( 0 ) {
            initViewer();
        }

    public slots:
        virtual void setScene ( Scene * const s ) {
            scene = s;
            connectScene();
        }
        virtual void adjustScene();
#ifdef WITH_GLEW
        virtual void setShader ( const QString & shader ) {
            makeCurrent();
            scene->setShader ( shader );
        }
#endif
        void setDefaultLight ( void );

    signals:
        void cameraModeChanged();

    protected:
        /**
        preDraw() default implementation does:
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        camera()->loadProjectionMatrix();
        camera()->loadModelViewMatrix();
        The camera modelView matrix set in preDraw() converts from the world to the camera coordinate systems. Vertices given in draw() can then be considered as being given in the world coordinate system. The camera is moved in this world using the mouse. This representation is much more intuitive than the default camera-centric OpenGL standard.
        */
        virtual void draw();
        virtual void keyPressEvent ( QKeyEvent * );
        virtual void init();
        void initViewer();
        void connectScene() {
            connect ( scene, SIGNAL ( sceneChanged() ), this, SLOT ( adjustScene() ) );
            connect ( scene, SIGNAL ( changed() ), this, SLOT ( updateGL() ) );
        }
        void setFog ( void );
        double performance ( void );
        //Scene* const scene;
        Scene* scene;
};

//=============================================================================
#endif // VIEWER_H
//=============================================================================
